package cn.rayland.rayland3d.activity;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import cn.rayland.app.yandktest.X3gStatus;
import cn.rayland.library.bean.FileTask;
import cn.rayland.library.bean.MachineState;
import cn.rayland.library.bean.MachineTask;
import cn.rayland.library.utils.ConvertUtils;
import cn.rayland.library.utils.MachineManager;
import cn.rayland.rayland3d.R;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = MainActivity.class.getSimpleName();
    private Button printStl;
    private Button printGcode;
    private Button printX3g;
    private Button controlPrint;
    private Button cancelPrint;
    private Button laserPrint;
    private Button pushWebSocket;
    private FileTask task = new FileTask();
    private final static String stlPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.stl";
    private final static String gcodePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.gcode";
    private final static String x3gPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.x3g";
    private final static String configPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/machine.conf";
    private ProgressDialog dialog;
    private MachineManager machineManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        copyTestFile();
        initView();
        //获取MachineManager对象
        machineManager = MachineManager.getInstance(this);
        //设置自定义机器配置
        machineManager.setCustomMachineConfig(configPath);
        //文件转换回调
        task.setConvertCallback(new ConvertUtils.ConvertCallback() {
            @Override
            public void onPreConvert(int type) {
                //开始转换前执行
                switch (type) {
                    case ConvertUtils.STL_TO_GCODE:
                        showProgressDialog(MainActivity.this, "convert stl to gcode...");
                        break;
                    case ConvertUtils.GCODE_TO_X3G:
                        showProgressDialog(MainActivity.this, "convert gcode to x3g...");
                        break;
                }
            }

            @Override
            public void onConvertProgress(int type, int progress) {
                //转换进度
                switch (type) {
                    case ConvertUtils.UPLOAD_STL:
                        dialog.setMessage("uploading stl file...");
                        if (progress == 100) {
                            dialog.setIndeterminate(true);
                            dialog.setMessage("slicing stl file...");
                        }
                        break;
                    case ConvertUtils.DOWNLOAD_STL:
                        dialog.setIndeterminate(false);
                        dialog.setMessage("downloading stl file...");
                        break;
                    case ConvertUtils.GCODE_TO_X3G:
                        dialog.setIndeterminate(false);
                        dialog.setMessage("convert gcode to x3g..");
                        break;
                }
                dialog.setProgress(progress);
            }

            @Override
            public void onConvertSuccess(int type, X3gStatus x3gStatus) {
                //转换成功执行
                dialog.dismiss();
                if (type == ConvertUtils.GCODE_TO_X3G) {
                    Toast.makeText(getApplicationContext(), "预计用时：" + x3gStatus.time + " S，预计用料：" + x3gStatus.length + " CM", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onConvertFailed(int type, String error) {
                //转换失败执行
                dialog.dismiss();
            }
        });
        //设置Gcode(M900,M114)回调
        task.setGcodeCallback(gcodeCallback);
        //设置Task(onStart,onFinished...)回调
        task.setTaskCallback(taskCallback);
    }

    //拷贝测试用的stL\gcode\x3g文件
    private void copyTestFile() {
        new Thread(){
            @Override
            public void run() {
                super.run();
                if(!new File(stlPath).exists()){
                    copyFromAssets(stlPath.substring(stlPath.lastIndexOf("/")+1), stlPath);
                }
                if(!new File(gcodePath).exists()){
                    copyFromAssets(gcodePath.substring(gcodePath.lastIndexOf("/")+1), gcodePath);
                }
                if(!new File(x3gPath).exists()){
                    copyFromAssets(x3gPath.substring(x3gPath.lastIndexOf("/")+1), x3gPath);
                }
                if(!new File(configPath).exists()){
                    copyFromAssets(configPath.substring(configPath.lastIndexOf("/")+1), configPath);
                }
            }
        }.start();
    }

    private void copyFromAssets(String assetsFilePath, String destiFilePath){
        InputStream is = null;
        FileOutputStream fos = null;
        try {
            is = getAssets().open(assetsFilePath);
            File file = new File(destiFilePath);
            if(!file.exists()){
                file.createNewFile();
            }
            fos = new FileOutputStream(file);
            byte[] bytes = new byte[1024];
            int length;
            while((length = is.read(bytes))!=-1){
                fos.write(bytes, 0, length);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //初始化各组件
    private void initView() {
        printStl = (Button) findViewById(R.id.stlPrint);
        printStl.setOnClickListener(this);
        printGcode = (Button) findViewById(R.id.gcodePrint);
        printGcode.setOnClickListener(this);
        printX3g = (Button) findViewById(R.id.x3gPrint);
        printX3g.setOnClickListener(this);
        controlPrint = (Button) findViewById(R.id.printControl);
        controlPrint.setOnClickListener(this);
        cancelPrint = (Button) findViewById(R.id.stop_print);
        cancelPrint.setOnClickListener(this);
        laserPrint = (Button) findViewById(R.id.laser_ranging);
        laserPrint.setOnClickListener(this);
        pushWebSocket = (Button) findViewById(R.id.push_websocket);
        pushWebSocket.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.stlPrint:
                task.setContent(new File(stlPath));
                task.setTaskName("test.stl");
                machineManager.sendTask(task, false);
                break;
            case R.id.gcodePrint:
                task.setContent(new File(gcodePath));
                task.setTaskName("test.gcode");
                machineManager.sendTask(task, false);
                break;
            case R.id.x3gPrint:
                task.setContent(new File(x3gPath));
                task.setTaskName("test.x3g");
                machineManager.sendTask(task, false);
                break;
            case R.id.printControl:
                startActivity(new Intent(MainActivity.this, ControlActivity.class));
                break;

            case R.id.laser_ranging:
                startActivity(new Intent(MainActivity.this, WolfsenActivity.class));
                break;

            case R.id.stop_print:
                machineManager.cancel(true);
                break;

            case R.id.push_websocket:
                startActivity(new Intent(MainActivity.this, PushWebSocketActivity.class));
                break;
        }
    }

    /**
     * 显示进度条提示
     * @param context
     * @param message
     */
	private void showProgressDialog(final Context context, String message) {
        if(dialog == null){
            dialog = new ProgressDialog(context);
        }
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		dialog.setIndeterminate(false);
		dialog.setMessage(message);
		dialog.setCanceledOnTouchOutside(false);
        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                //停止文件转换
                ConvertUtils.cancelConvert();
            }
        });
		dialog.show();
	}

    private MachineTask.TaskCallback taskCallback = new MachineTask.TaskCallback() {
        @Override
        public void onStart(MachineTask machineTask, X3gStatus x3gStatus) {
            //开始执行前调用此方法
            Log.d(TAG, "onStart");
            startActivity(new Intent(MainActivity.this, StateActivity.class));
            if (EasySharePreference.getPrefInstance(getApplicationContext()).getBoolean("ifpush", false)){
                WebSocketPusher.startPush(EasySharePreference.getPrefInstance(getApplicationContext()).getString("pushAddress", "")+":"+EasySharePreference.getPrefInstance(getApplicationContext()).getInt("pushPort", 0),
                        EasySharePreference.getPrefInstance(getApplicationContext()).getInt("pushTime",10000), machineManager.getMachineState());
            }
        }

        @Override
        public void onError(MachineTask machineTask, MachineState machineState) {
            //执行遇到错误调用此方法
            Log.d(TAG, "onError");
            WebSocketPusher.stopPush();
        }

        @Override
        public void onCancel(MachineTask machineTask, MachineState machineState) {
            //取消执行时调用此方法
            Log.d(TAG, "onCancel");
            WebSocketPusher.stopPush();
        }

        @Override
        public void onFinished(MachineTask machineTask, MachineState machineState) {
            //执行结束后调用此方法
            Log.d(TAG, "onFinished");
            WebSocketPusher.stopPush();
        }
    };

    private MachineTask.GcodeCallback gcodeCallback = new MachineTask.GcodeCallback() {
        @Override
        public void onM900(float distance) {
            //M900回调
            Log.d(TAG, "height = " + distance + "");
        }

        @Override
        public void onM114(float[] positions) {
            //M114回调
            Log.d(TAG, "坐标 = " + positions[0] + "/" + positions[1] + "/" + positions[2]);
        }
    };
}
